using System;
using System.Collections.Generic;
using System.Text;

namespace qtControlLibrary
{
    class StateMachine<entityType>
    {

	    private entityType			_Owner;

        private State<entityType>	_NextState;
        private State<entityType>	_CurrentState;
        private State<entityType>	_PreviousState;
        private State<entityType>	_GlobalState;

        public entityType Owner { get { return _Owner; } set { _Owner = value; } }

        public State<entityType> NextState { get { return _NextState; } set { _NextState = value; } }
        public State<entityType> CurrentState { get { return _CurrentState; } set { _CurrentState = value; } }
        public State<entityType> PreviousState { get { return _PreviousState; } set { _PreviousState = value; } }
        public State<entityType> GlobalState { get { return _GlobalState; } set { _GlobalState = value; } }


	    /// call to update state machine
	    public void	Update()
	    {
		    if (_GlobalState != null) _GlobalState.Execute(_Owner);
            if (_CurrentState != null) _CurrentState.Execute(_Owner);

		    if ((_NextState != null) && (_NextState != _CurrentState))
		    {
			    ChangeState(_NextState);
                _NextState = null;
		    }
	    }

	    public void	ChangeState(State<entityType>	pNewState)
	    {
		    _PreviousState = _CurrentState;
            if (_CurrentState != null) _CurrentState.Exit(_Owner);
		    _CurrentState = pNewState;
            if (_CurrentState != null) _CurrentState.Enter(_Owner);
	    }


	    public void	RevertToPreviousState()
	    {
		    ChangeState(_PreviousState);
	    }


	    public bool	HandleMessage(Telegram msg)
	    {
            if (_CurrentState != null && _CurrentState.OnMessage(_Owner, msg))
		    {
			    return true;
		    }
            if (_GlobalState != null && _GlobalState.OnMessage(_Owner, msg))
		    {
			    return true;
		    }
		    return false;
	    }

	    public bool IsState(State<entityType>	pState){return (_CurrentState == pState)?true:false;}

	    public StateMachine(entityType pOwner)
	    {
            _Owner = pOwner;
		    _CurrentState = null;
		    _PreviousState = null;
		    _GlobalState = null;
		    _NextState = null;
	    }

    }
}
